/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.mochaccino.framework.rest;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.StreamingOutput;
import nl.captcha.Captcha;
import nl.captcha.gimpy.DropShadowGimpyRenderer;
import nl.captcha.servlet.CaptchaServletUtil;
import nl.captcha.text.producer.DefaultTextProducer;

@Path( CaptchaResource.PATH_CAPTCHA )
public final class CaptchaResource {

	/** The Captcha Builder */
	private Captcha.Builder builder;

	/** The URI Path */
	public static final String PATH_CAPTCHA = "/captcha";

	/** The Session Key */
	public static final String SESSION_KEY_CAPTCHA_ANSWER = "captcha_answer";

	/** Constructor */
	@Inject
	public CaptchaResource( Captcha.Builder builder ) {
		this.builder = builder;
	}

	/** Constructor */
	public CaptchaResource() {
		this( new Captcha.Builder( 125, 60 ).addText( new DefaultTextProducer() ).gimp( new DropShadowGimpyRenderer() ) );
	}

	/** Check Answer */
	public static final boolean checkAnswer( HttpServletRequest request, String answer ) {
		if ( request == null ) {
			return false;
		}

		return checkAnswer( request.getSession(false), answer );
	}

	/** Check Captcha Answer */
	public static boolean checkAnswer( HttpSession session, String answer ) {
		if ( session == null ) {
			return false;
		}

		if ( answer == null ) {
			return false;
		}

		String sessionAnswer = (String) session.getAttribute( SESSION_KEY_CAPTCHA_ANSWER );
		if ( sessionAnswer == null ) {
			return false;
		}

		if ( sessionAnswer.equals( answer ) ) {
			return true;
		}

		return false;
	}

	@Path( "/" )
	@GET
	@Produces( "images/*" )
	@Consumes( "*/*" )
	public Response captcha( @Context HttpServletRequest request ) {
		HttpSession session = request.getSession( false );
		final Captcha captcha = builder.build();
		session.setAttribute( SESSION_KEY_CAPTCHA_ANSWER, captcha.getAnswer() );

		CacheControl cache = new CacheControl();
		cache.setNoCache( true );
		cache.setNoStore( true );
		cache.setNoTransform( true );
		cache.setPrivate( true );
		cache.setMustRevalidate( true );
		cache.setProxyRevalidate( true );

		ResponseBuilder response = Response.ok();
		response.cacheControl( cache );
		response.lastModified( new Date() );
		response.expires( new Date() );
		response.type( "images/*" );
		response.entity( new StreamingOutput() {
			@Override
			public void write( OutputStream output ) throws IOException, WebApplicationException {
				CaptchaServletUtil.writeImage( output, captcha.getImage() );
			}
		} );
		return response.build();
	}
}
